#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
应用程序框架分析器 - API客户端示例
演示如何调用API服务进行应用分析
"""

import os
import sys
import time
import json
import argparse
import requests
from pathlib import Path
from typing import Dict, Any, Optional

class AppAnalyzerClient:
    """应用框架分析器API客户端"""
    
    def __init__(self, api_url: str = "http://localhost:5000"):
        """
        初始化客户端
        
        Args:
            api_url: API服务器URL
        """
        self.api_url = api_url.rstrip('/')
    
    def health_check(self) -> Dict[str, Any]:
        """检查API服务器健康状态"""
        url = f"{self.api_url}/api/health"
        response = requests.get(url)
        response.raise_for_status()
        return response.json()
    
    def upload_app(self, file_path: str, platform: str = "auto") -> Dict[str, Any]:
        """
        上传应用进行分析
        
        Args:
            file_path: 应用文件路径
            platform: 应用平台，默认为auto自动检测
            
        Returns:
            任务信息字典
        """
        url = f"{self.api_url}/api/upload"
        
        # 确保文件存在
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 打开文件并上传
        with open(file_path, 'rb') as f:
            files = {'file': (os.path.basename(file_path), f)}
            data = {'platform': platform}
            
            print(f"正在上传文件 {os.path.basename(file_path)}...")
            response = requests.post(url, files=files, data=data)
            response.raise_for_status()
        
        result = response.json()
        print(f"上传成功，任务ID: {result['task_id']}")
        return result
    
    def get_task_status(self, task_id: str) -> Dict[str, Any]:
        """
        获取任务状态
        
        Args:
            task_id: 任务ID
            
        Returns:
            任务状态字典
        """
        url = f"{self.api_url}/api/tasks/{task_id}"
        response = requests.get(url)
        response.raise_for_status()
        return response.json()
    
    def wait_for_completion(self, task_id: str, interval: int = 5, timeout: int = 1800) -> Dict[str, Any]:
        """
        等待任务完成
        
        Args:
            task_id: 任务ID
            interval: 检查间隔（秒）
            timeout: 超时时间（秒）
            
        Returns:
            最终任务状态字典
        """
        start_time = time.time()
        
        while True:
            # 检查是否超时
            if time.time() - start_time > timeout:
                raise TimeoutError(f"等待任务完成超时（{timeout}秒）")
            
            # 获取当前任务状态
            status = self.get_task_status(task_id)
            
            if status['status'] == 'completed':
                print(f"任务完成！检测到 {status['result']['frameworks_count']} 个框架")
                return status
            elif status['status'] == 'failed':
                error_msg = status.get('error', '未知错误')
                raise RuntimeError(f"任务失败: {error_msg}")
            else:
                print(f"任务状态: {status['status']}，继续等待...")
                time.sleep(interval)
    
    def download_report(self, task_id: str, format: str = "html", output_path: Optional[str] = None) -> str:
        """
        下载分析报告
        
        Args:
            task_id: 任务ID
            format: 报告格式（html或json）
            output_path: 输出路径，默认为当前目录
            
        Returns:
            保存的报告文件路径
        """
        url = f"{self.api_url}/api/reports/{task_id}?format={format}"
        
        # 确定输出目录
        if not output_path:
            output_path = os.getcwd()
        os.makedirs(output_path, exist_ok=True)
        
        # 确定输出文件名
        if format == "html":
            output_file = os.path.join(output_path, f"report_{task_id}.html")
        else:
            output_file = os.path.join(output_path, f"result_{task_id}.json")
        
        # 下载报告
        print(f"正在下载{format}报告...")
        response = requests.get(url)
        response.raise_for_status()
        
        # 保存报告
        with open(output_file, 'wb') as f:
            f.write(response.content)
        
        print(f"报告已保存至: {output_file}")
        return output_file
    
    def cleanup_task(self, task_id: str, include_reports: bool = False, remove_task: bool = False) -> Dict[str, Any]:
        """
        清理任务文件
        
        Args:
            task_id: 任务ID
            include_reports: 是否同时清理报告
            remove_task: 是否从任务列表中移除
            
        Returns:
            操作结果字典
        """
        url = f"{self.api_url}/api/cleanup"
        data = {
            'task_id': task_id,
            'include_reports': include_reports,
            'remove_task': remove_task
        }
        
        response = requests.post(url, json=data)
        response.raise_for_status()
        return response.json()


def main():
    """命令行入口函数"""
    parser = argparse.ArgumentParser(description="应用框架分析器API客户端")
    
    # 基本参数
    parser.add_argument("--api-url", default="http://localhost:5000", help="API服务器URL")
    
    # 子命令
    subparsers = parser.add_subparsers(dest="command", help="子命令")
    
    # 健康检查命令
    health_parser = subparsers.add_parser("health", help="检查API服务器健康状态")
    
    # 上传应用命令
    upload_parser = subparsers.add_parser("upload", help="上传应用进行分析")
    upload_parser.add_argument("file", help="应用文件路径")
    upload_parser.add_argument("--platform", default="auto", help="应用平台类型")
    upload_parser.add_argument("--wait", action="store_true", help="等待分析完成")
    upload_parser.add_argument("--download", action="store_true", help="下载分析报告")
    upload_parser.add_argument("--format", default="html", choices=["html", "json"], help="报告格式")
    upload_parser.add_argument("--output", help="报告输出路径")
    
    # 获取任务状态命令
    status_parser = subparsers.add_parser("status", help="获取任务状态")
    status_parser.add_argument("task_id", help="任务ID")
    
    # 等待任务完成命令
    wait_parser = subparsers.add_parser("wait", help="等待任务完成")
    wait_parser.add_argument("task_id", help="任务ID")
    wait_parser.add_argument("--interval", type=int, default=5, help="检查间隔（秒）")
    
    # 下载报告命令
    download_parser = subparsers.add_parser("download", help="下载分析报告")
    download_parser.add_argument("task_id", help="任务ID")
    download_parser.add_argument("--format", default="html", choices=["html", "json"], help="报告格式")
    download_parser.add_argument("--output", help="报告输出路径")
    
    # 清理任务命令
    cleanup_parser = subparsers.add_parser("cleanup", help="清理任务文件")
    cleanup_parser.add_argument("task_id", help="任务ID")
    cleanup_parser.add_argument("--include-reports", action="store_true", help="同时清理报告")
    cleanup_parser.add_argument("--remove-task", action="store_true", help="从任务列表中移除")
    
    args = parser.parse_args()
    
    # 创建客户端实例
    client = AppAnalyzerClient(api_url=args.api_url)
    
    try:
        # 处理命令
        if args.command == "health":
            result = client.health_check()
            print(f"服务器状态: {result['status']}")
            print(f"时间戳: {result['timestamp']}")
            print(f"版本: {result['version']}")
            
        elif args.command == "upload":
            # 上传应用
            result = client.upload_app(args.file, args.platform)
            task_id = result['task_id']
            
            # 如果需要等待完成
            if args.wait:
                result = client.wait_for_completion(task_id)
                
                # 如果需要下载报告
                if args.download:
                    client.download_report(task_id, args.format, args.output)
            
        elif args.command == "status":
            result = client.get_task_status(args.task_id)
            print(f"任务ID: {result['task_id']}")
            print(f"状态: {result['status']}")
            print(f"创建时间: {result['created_at']}")
            print(f"更新时间: {result['updated_at']}")
            
            if 'result' in result:
                print(f"检测到的框架数: {result['result']['frameworks_count']}")
                print(f"报告URL: {args.api_url}{result['result']['report_url']}")
            
        elif args.command == "wait":
            result = client.wait_for_completion(args.task_id, args.interval)
            print(f"任务完成！检测到 {result['result']['frameworks_count']} 个框架")
            print(f"报告URL: {args.api_url}{result['result']['report_url']}")
            
        elif args.command == "download":
            output_file = client.download_report(args.task_id, args.format, args.output)
            print(f"报告已下载至: {output_file}")
            
        elif args.command == "cleanup":
            result = client.cleanup_task(args.task_id, args.include_reports, args.remove_task)
            print(f"清理结果: {result['message']}")
            
        else:
            parser.print_help()
            
    except Exception as e:
        print(f"错误: {str(e)}")
        sys.exit(1)


if __name__ == "__main__":
    main() 
